from common.cache.pool_cache import KeyPoolCache
from common.utils.tools import ToolsUtil
from exception import AppException


class MusicOpenAiHkServer:
    """
    https://openai-hk.com/
    """
    def __init__(self):
        self.baseUrl = "https://api.openai-hk.com/sunoapi"

    async def submit(self, params: dict):
        if params.get("type") == "lyric":
            # 歌词模式
            data = {
                # 歌曲标题
                "title": params.get("title"),
                # 歌曲描述
                "prompt": params.get("prompt", ""),
                # 歌曲风格
                "tags": params.get("tags", ""),
                # 版本模型
                "mv": params.get("mv", "chirp-v3-0"),
                # 续写时长: [暂不对接]
                "continue_at": 0,
                # 续写音频: [暂不对接]
                "continue_clip_id": "",
                # 纯音乐
                "make_instrumental": bool(params.get("make_instrumental", False))
            }
        else:
            # 灵感模式
            data = {
                # 版本模型
                "mv": params.get("mv", "chirp-v3-0"),
                # 歌曲名称
                "prompt": params.get("title"),
                # 灵感创作
                "gpt_description_prompt": params.get("prompt"),
                # 纯音乐
                "make_instrumental": bool(params.get("make_instrumental", False))
            }

        # 获取密钥
        token: str = await self.get_apikey()

        # 提交任务
        response = await ToolsUtil.post_curl(
            url=f"{self.baseUrl}/generate",
            headers={
                "Content-Type": "application/json",
                "Authorization": "Bearer " + token
            },
            data=data
        )

        # 结果处理
        if response.get("error"):
            error = response["error"].get("message", "系统错误")
            raise Exception(error)

        # 结果返回
        return response

    async def fetch(self, clips_id: str) -> dict:
        """
        获取生成结果

        Returns:
            # 成功
            [
                {
                    "status": "complete",
                    "image_large_url": "https://cdn1.suno.ai/image.jpeg",
                    "image_url": "https://cdn1.suno.ai/image.jpeg",
                    "audio_url": "https://cdn1.suno.ai/f5b8355d-3233-4d49-b20d-ea377848153c.mp3"
                }
            ]
            # 失败
            {'error': {'code': '1000', 'message': '身份验证失败。'}}

        Author:
            zero
        """
        token: str = await self.get_apikey()
        try:
            response = await ToolsUtil.get_curl(
                url=f"{self.baseUrl}/feed/{clips_id}",
                headers={
                    "Content-Type": str("application/json"),
                    "Authorization": str("Bearer " + token)
                }
            )
            return response
        except Exception as e:
            raise Exception(str(e))

    @classmethod
    async def get_apikey(cls) -> str:
        """ 获取密钥 """
        apikey = await KeyPoolCache(scene="music", channel="openai_hk").get_key() or {}
        if not apikey or not apikey.get("api_key"):
            raise AppException("尚未配置密钥,请与管理员联系")
        return apikey["api_key"]
